package com.CGFrame.struts.bean.make;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import com.CGFrame.struts.POJOs.Element;
import com.CGFrame.struts.POJOs.Make;
import com.CGFrame.struts.POJOs.Makerelation;
import com.CGFrame.struts.POJOs.Reguser;
import com.CGFrame.struts.POJOs.Shot;
import com.CGFrame.struts.POJOs.Status;
import com.CGFrame.struts.POJOs.Task;
import com.CGFrame.struts.bean.ProjectOperate;
import com.CGFrame.struts.bean.ProjectOperateFactory;
import com.CGFrame.struts.bean.gant.GantBean;
import com.CGFrame.struts.bean.keypath.EventNode;
import com.CGFrame.struts.bean.keypath.KeypathBean;
import com.CGFrame.struts.bean.message.MessageBean;
import com.CGFrame.struts.bean.task.TaskBean;
import com.CGFrame.struts.bean.unit.FilePathGenerator;

public class MakeBean {
	Make make;

	Date Ve = null;

	Date Vl = null;

	/**
	 * ��ʼ��
	 * 
	 * @param makeId
	 */
	public MakeBean(int makeId) {
		ProjectOperate pop = ProjectOperateFactory.getprojectOperate();
		make = (Make) pop.UniqueQuery("Make", "makeId," + makeId);
		
	}

	/**
	 * ��ʼ��
	 * 
	 * @param make
	 */
	public MakeBean(Make make) {
		this.make = make;
//		calMakeTime();
	}

	void calMakeTime() {
		int makeId = make.getMakeId();
		if (!(make.getElement() == null))
		{
			Element element =make.getElement();
			Date date = element.getPlanStartTime();
			if (date==null)
			{
				return ;
			}
			date.setHours(8);
			KeypathBean keypath = new KeypathBean();
			EventNode []makes = keypath.Init(element, "Element");
			for (int i = 0 ; i<makes.length;i++)
			{
				if (makes[i].getId()==makeId  )
				{
					
					Ve = dateAddHour(date,makes[i].getVe());
					Vl = dateAddHour(date,makes[i].getVl());
	//				System.out.println(make.getMakeName()+":"+date+"���翪ʼ��"+makes[i].getVe()+"-��ʼʱ��-"+Ve);
				}
			}
		}
		if (!(make.getShot()==null))
		{
			Shot shot = make.getShot();
			Date date = shot.getPlanStartTime();
			if (date==null)
			{
				return; 
			}
			date.setHours(8);
			KeypathBean keypath = new KeypathBean();
			EventNode []makes = keypath.Init(shot, "Shot");
			for (int i = 0 ; i<makes.length;i++)
			{
				if (makes[i].getId()==makeId  )
				{
					
					Ve = dateAddHour(date,makes[i].getVe());
					Vl = dateAddHour(date,makes[i].getVl());
	//				System.out.println(make.getMakeName()+":"+date+"���翪ʼ��"+makes[i].getVe()+"-��ʼʱ��-"+Ve);
				}
			}
		}
	}
	
	public String  getType()
	{
		if( make.getShot()== null )
			return "Element";
		else
			return "Shot";
	}
	public int getUnitId()
	{
		if(make.getShot() != null)
		{
			return make.getShot().getShotId();
		}
		else if (make.getElement()!=null)
		{
			return make.getElement().getElementId();
		}
		else 
			return 0;
	}
	
	
	public  String getFilePathforMake(int Flag)
	{
//		path="CCTV/Project/scenes/Assets/Production/Characters/ShiTong/";   
//		path="CCTV/Project/scenes/Episodes/Episode001/Production/Shot/Shot002/";
		
		StringBuffer unitPath = new StringBuffer();
		if ( this.getType().equals("Shot") )
		{
			unitPath =(StringBuffer)FilePathGenerator.getFilePath(this.getUnitId(),"Shot").get(0);
		}
		else
		{
			unitPath =(StringBuffer)FilePathGenerator.getFilePath(this.getUnitId(),"Element").get(0);
		}
		if (FilePathGenerator.MakeFile == Flag)
		{
			unitPath.append(make.getMakeName()).append("/Working/");
		}
		else if (FilePathGenerator.FinishedMakeFile == Flag)
		{
			unitPath.append(make.getMakeName()).append("/Approved/");
		}
		return unitPath.toString();
	}
	public void updateName(String name)
	{
		ProjectOperate pop = ProjectOperateFactory.getprojectOperate();
		this.make.setMakeName(name);
		pop.saveObject(this.make);
	}
	
	public void updateExceptHours(int hours)
	{
		ProjectOperate pop = ProjectOperateFactory.getprojectOperate();
		this.make.setExceptHours(hours);
		Iterator ite_tasks = make.getTasks().iterator();
		while(ite_tasks.hasNext())
		{
			TaskBean taskBean = new TaskBean((Task)ite_tasks.next());
			taskBean.updateExpectHours(hours);
		}
		pop.saveObject(make);
	}

	/**
	 * ���MakeRelation�� ȡ��ǰ������
	 * 
	 * @return
	 */
	public Vector getPreMakes() {
		Vector vec_PreMakes = new Vector();
		Iterator ite_PreMakeRelations = make.getMakerelationsForMake2id()
				.iterator();
		while (ite_PreMakeRelations.hasNext()) {
			Makerelation makerelation = (Makerelation) ite_PreMakeRelations
					.next();
			Make preMake = makerelation.getMakeByMake1id();
			vec_PreMakes.add(preMake);
		}
		return vec_PreMakes;
	}

	/**
	 * ���MakeRelation�� ȡ���������
	 * 
	 * @return
	 */
	public Vector getSufMakes() {
		Vector vec_SufMakes = new Vector();
		Iterator ite_SufMakeRelations = make.getMakerelationsForMake1id()
				.iterator();
		while (ite_SufMakeRelations.hasNext()) {
			Makerelation makerelation = (Makerelation) ite_SufMakeRelations
					.next();
			Make preMake = makerelation.getMakeByMake2id();
			vec_SufMakes.add(preMake);
		}
		return vec_SufMakes;
	}

	/**
	 * �жϼ���this.make-->make2���Ƿ��г� ����Ȧͼ ��ͬʱmake��make2����4�жϵĻ������ж�����ķ�����
	 * 
	 * @param make2
	 * @return
	 */
	public boolean isDCG(Make make2) {
		// ���make1 �� make2 �Ѿ��й�j ֱ�ӷ���true

		boolean boo_isDcg = false;
		Iterator ite_PreMakes = this.getPreMakes().iterator();
		while (ite_PreMakes.hasNext()) {
			Make preMake = (Make) ite_PreMakes.next();
			// System.out.println( "preMake:"+preMake.getMakeId() );
			// System.out.println( "Make2:"+make2.getMakeId() );
			if (preMake.getMakeId().compareTo(make2.getMakeId()) == 0) {
				// System.out.println("��Ȧ");
				boo_isDcg = true;
				// System.out.println("����Ȧͼô? "+boo_isDcg);
				break;

			} else {
				// System.out.println("��ûȦ");
				MakeBean makeBean2 = new MakeBean(preMake);
				boo_isDcg = makeBean2.isDCG(make2);
				// System.out.println("����Ȧͼô? "+boo_isDcg);
				if (boo_isDcg)
					break;
			}
		}
		// System.out.println("����Ȧͼô? "+boo_isDcg);
		return boo_isDcg;
	}

	/**
	 * ���makeId �жϼ���this.make-->make2���Ƿ��г� ����Ȧͼ ��ͬʱmake��make2����4�жϵĻ������ж�����ķ�����
	 * 
	 * @param make2Id
	 * @return
	 */
	public boolean isDCG(int make2Id) {
		ProjectOperate pop = ProjectOperateFactory.getprojectOperate();
		Make make2 = (Make) pop.UniqueQuery("Make", "makeId," + make2Id);
		return this.isDCG(make2);
	}

	/**
	 * �ж��ڹ�ϵ�����Ƿ���this.make-->make2
	 * 
	 * @param make2
	 * @return
	 */
	public boolean isExistRel(Make make2) {
		Iterator ite_SufMakes = this.getSufMakes().iterator();
		while (ite_SufMakes.hasNext()) {
			Make make = (Make) ite_SufMakes.next();
			if (make.getMakeId().compareTo(make2.getMakeId()) == 0) {
				return true;
			}
		}
		return false;
	}

	/**
	 * ���this.make-->make2 ��ϵ ����true��ʾ�ɹ��� falseʧ�ܡ�������ԭ��
	 * 
	 * @param make2
	 * @return
	 */
	public boolean addMakeRelation(Make make2) {
		ProjectOperate pop = ProjectOperateFactory.getprojectOperate();
		if (this.isExistRel(make2)) {
//			System.out.println("��ϵ�Ѵ���:" + make.getMakeName() + "-->"
//					+ make2.getMakeName());
			return false;
		}
		if (this.isDCG(make2)) {
//			System.out.println("��ϵ������Ȧͼ:" + make.getMakeName() + "-->"
//					+ make2.getMakeName());
			return false;
		}
		MakeBean make2Bean = new MakeBean(make2);
		if (make2Bean.isDCG(this.make)) {
//			System.out.println("��ϵ����:" + make.getMakeName() + "-->"
//					+ make2.getMakeName());
			return false;
		}
		Makerelation makerelation = new Makerelation();
		makerelation.setMakeByMake1id(make);
		makerelation.setMakeByMake2id(make2);
		pop.saveObject(makerelation);
		return true;
	}

	/**
	 * �ж�this.make���Ƿ����taskname��task
	 * 
	 * @param TaskName
	 * @return
	 */
	public boolean isExist(String taskName) {
		Iterator ite_Tasks = make.getTasks().iterator();
		while (ite_Tasks.hasNext()) {
			Task task = (Task) ite_Tasks.next();
			if (task.getTaskName().equals(taskName)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * this.Make���������
	 * 
	 * @param reguser
	 *            ��ֱ�ӷ�������
	 * @param taskName
	 *            ������,ͬ�����
	 * @param taskDescription
	 * @param exceptHours
	 *            �ƻ�ʱ��
	 * @return ��������Ƿ�ɹ���String.
	 */
	public String addTask(Reguser reguser, String taskName,
			String taskDescription, int exceptHours) {
		if (this.isExist(taskName))
			return "Make\"" + make.getMakeName() + "\"add task \"" + taskName
					+ "\" has existed";
		ProjectOperate pop = ProjectOperateFactory.getprojectOperate();
		Task task = new Task();
		Status status;
		if (reguser == null) {
			status = (Status) pop.UniqueQuery("Status",
					"statusType,Task,statusName,HasInput");
		} else {
			status = (Status) pop.UniqueQuery("Status",
					"statusType,Task,statusName,HasAssigned");
			task.setReguser(reguser);
			Status makeStatus = (Status)pop.UniqueQuery("Status", "statusName,HasAssigned,statusType,Make");
			make.setStatus(makeStatus);
			pop.saveObject(make);
		}
		task.setStatus(status);
		task.setExceptHours(exceptHours);
		task.setMake(make);
		task.setTaskDescription(taskDescription);
		task.setTaskName(taskName);
		pop.saveObject(task);
		return task.getTaskId().toString();

	}

	/**
	 * ȡ���������翪ʼʱ��
	 * 
	 * @return ���������翪ʼʱ��
	 */
	public Date getVe() {
		calMakeTime();
		return Ve;

	}
	/**
	 * ȡ���������?ʼʱ��
	 * 
	 * @return ���������?ʼʱ��
	 */
	public Date getVl() {
		return Vl;
	}
	public Date getExactStartTime()
	{
		Date date = null;
		Iterator ite_Tasks = make.getTasks().iterator();
		while(ite_Tasks.hasNext())
		{
			Task task = (Task)ite_Tasks.next();
			if (task.getExactStartTime()!=null && ( date ==null || date.after(task.getExactStartTime())) ) //任务已经开始 并且 之前任务开始晚于现在任务时才赋值
			{
				date = task.getExactStartTime();
			}
		}
		if (date==null)
		{
			date = new Date();
		}
		return date;
	}
	public Date getExactEndTime()
	{
		Date date = null;
		Iterator ite_Tasks = make.getTasks().iterator();
		while(ite_Tasks.hasNext())
		{
			Task task = (Task)ite_Tasks.next();
			if (task.getStatus().getStatusId() !=7)
			{
				return new Date();
			}
			else if (task.getExactEndTime()!=null && (date==null || date.before(task.getExactEndTime()))) //任务已经结束， 之前任务结束早于现在这个任务才赋值
			{
				date = task.getExactEndTime();
			}
		}
		if (date==null)
		{
			date = new Date();
		}
		return date;
	}
	public String getName()
	{
		return make.getMakeName();
	}
	public String getTips()
	{
		StringBuffer tip = new StringBuffer();
		Iterator tasks = make.getTasks().iterator();
		while(tasks.hasNext())
		{
			Task task = (Task)tasks.next();
			if (task.getReguser()!=null)
			{
				tip.append(task.getReguser().getRegName()).append("  ");						
			}
		}
		return tip.toString();
	}
	public double getPercent()
	{
		String statusName = make.getStatus().getStatusName();
		return GantBean.getPercentByStatus(statusName);
	}
	Date dateAddHour(Date date , int totalHour)//�����ĩ
	{
		int day = totalHour/8;
		int hour = totalHour%8;
		GregorianCalendar  cal = new GregorianCalendar();
		cal.setTime(date);
		int dayOfWeek1 = cal.get(Calendar.DAY_OF_WEEK); //�ܼ�
//		System.out.println("1�����յģ��������ܼ���"+dayOfWeek1);
		if (dayOfWeek1 == 1 )cal.add(GregorianCalendar.DATE, 1);
		if (dayOfWeek1 == 7 )cal.add(GregorianCalendar.DATE, 2);
		for (int i = 1 ; i<=day ; i++)
		{
			cal.add(GregorianCalendar.DATE, 1);
			int dayOfWeek2 = cal.get(Calendar.DAY_OF_WEEK); //��1����ܼ�
//			System.out.println("1�����յģ�����һ����������ܼ���"+dayOfWeek2);
			if (dayOfWeek2 == 7 )cal.add(GregorianCalendar.DATE, 2); //�������ټ�2��
		}
		cal.add(GregorianCalendar.HOUR, hour);
		int dayOfWeek3 = cal.get(Calendar.DAY_OF_WEEK); //��hour���ܼ�
		if (dayOfWeek3 == 7 )cal.add(GregorianCalendar.DATE, 2); //�������ټ�2��
		return cal.getTime();
	}
	public String changeStatusById(String statusId){
		if ( statusId.equals(make.getStatus().getStatusId().toString()) )
		{
		//	changeShotStatus();
			return null;
		}
		ProjectOperate pop = ProjectOperateFactory.getprojectOperate();
		Status status = (Status) pop.UniqueQuery("Status", "statusType,Make,statusId," +statusId);
		if ( status == null){
		//	changeShotStatus();
			return null;
		}
		make.setStatus(status);
		pop.saveObject(make);
		Status taskStatus = (Status) pop.UniqueQuery("Status","statusName,"+status.getStatusName()+",statusType,Task");
		if (taskStatus == null)
		{
		//	changeShotStatus();
			return status.getStatusName();
		}
		Iterator  ite_Tasks =make.getTasks().iterator();
		while (ite_Tasks.hasNext())
		{
			Task task= (Task)ite_Tasks.next();
			task.setStatus(taskStatus);
			pop.saveObject(task);
		}
		changeElementShotStatus();
		return status.getStatusName();
	}


	public void sendRelativeMessage(String regUserId, String content) {
		Iterator ite_Tasks = make.getTasks().iterator();
		MessageBean messageBean = MessageBean.getMessageBean();
		ProjectOperate pop = ProjectOperateFactory.getprojectOperate();
		Reguser reguser = (Reguser)pop.UniqueQuery("Reguser", "regUserId,"+regUserId);
		while(ite_Tasks.hasNext())
		{
			Task task = (Task)ite_Tasks.next();
			try
			{
				String empName =task.getReguser().getEmployee().getEmpName();
				messageBean.send(reguser.getEmployee().getEmpName(),empName,task.getTaskName(),task.getTaskName()+": "+ content,"");
			}
			catch( Exception e)
			{
			}
		}
	}

	
	/**
	 * 根据make的状态,改变shot的状态.如果全部finished,则shot为finished.如全部为HasInput,则shot为HasInput.其他则为HasAssigned.
	 *
	 */
	public void changeElementShotStatus(){
		ProjectOperate pop = ProjectOperateFactory.getprojectOperate();
		Status inputSStatus = (Status) pop.UniqueQuery("Status","statusName,HasInput,statusType,Shot");
		Status assignedSStatus = (Status) pop.UniqueQuery("Status","statusName,HasAssigned,statusType,Shot");
		Status finishedSStatus = (Status) pop.UniqueQuery("Status","statusName,Finished,statusType,Shot");
		Status inputEStatus = (Status) pop.UniqueQuery("Status","statusName,HasInput,statusType,Shot");
		Status assignedEStatus = (Status) pop.UniqueQuery("Status","statusName,HasAssigned,statusType,Shot");
		Status finishedEStatus = (Status) pop.UniqueQuery("Status","statusName,Finished,statusType,Shot");
		Shot shot=make.getShot();
		Element element = make.getElement();
		if(shot!=null)
		{
			Set makes=shot.getMakes();
			for(Iterator iter=makes.iterator();iter.hasNext();){
				String name=((Make)iter.next()).getStatus().getStatusName();
				if(name.equals("Finished")){
					shot.setStatus(finishedSStatus);
				}else if(name.equals("HasInput")){
					shot.setStatus(inputSStatus);
				}else{
					shot.setStatus(assignedSStatus);
					//pop.saveObject(shot);
					break ;
				}
			}
			pop.saveObject(shot);			
		}
		else if (element!=null)
		{
			Set makes=element.getMakes();
			for(Iterator iter=makes.iterator();iter.hasNext();){
				String name=((Make)iter.next()).getStatus().getStatusName();
				if(name.equals("Finished")){
					element.setStatus(finishedEStatus);
				}else if(name.equals("HasInput")){
					element.setStatus(inputEStatus);
				}else{
					element.setStatus(assignedEStatus);
					//pop.saveObject(shot);
					break ;
				}
			}
			pop.saveObject(element);
		}
	}

}
